﻿using UnityEngine;
using System.Collections;

//------------------------------------------------------------
// shaco Framework
// Copyright © 2017-2023 chang.liu All rights reserved.
// Feedback: 449612236@qq.com
//------------------------------------------------------------

namespace shaco
{
    public class LocalizationComponent : MonoBehaviour
    {
        public enum TargetType
        {
            None,
            Text,
            Image,
            Prefab,
            Custom
        }

        virtual public TargetType type { get { return _type; } protected set { _type = value; } }
        [SerializeField]
        [HideInInspector]
        private TargetType _type = TargetType.Text;

        virtual public string languageKey
        {
            get { return _languageKey; }
            set
            {
                if (_languageKey != value)
                {
                    _languageKey = value;
                    UpdateLocalization();
                }
            }
        }

        [SerializeField]
        [HideInInspector]
        protected string _languageKey = string.Empty;

        //是否异步加载图片或者prefab
        [HideInInspector]
        public bool isAsyncLoad = true;

        [HideInInspector]
        public string[] formatParams = new string[0];

        private bool isInited = false;

        private GameObject _currentLocalizationPrefab = null;

        void OnEnable()
        {
            if (isInited)
                UpdateLocalization();
        }

        void Start()
        {
            if (!isInited)
            {
                isInited = true;
                UpdateLocalization();
            }
        }

        void Reset()
        {
            if (!ChangeTargetType(this.type))
            {
                this.type = TargetType.None;
            }
        }

        virtual public bool ChangeTargetType(TargetType type)
        {
            bool isValid = true;
            switch (type)
            {
                case TargetType.Text: isValid = CanChangeTargetTypeText(); break;
                case TargetType.Image: isValid = CanChangeTargetTypeImage(); break;
                case TargetType.Prefab: isValid = CanChangeTargetTypePrefab(); break;
                case TargetType.Custom: isValid = CanChangeTargetTypeCustom(); break;
                default: Debug.LogError("LocalizationComponent unsupport target type=" + type); isValid = false; break;
            }

            if (isValid)
                this.type = type;
            return isValid;
        }

        public void UpdateLocalization()
        {
            switch (type)
            {
                case TargetType.None: /*do nothing*/ break;
                case TargetType.Text:
                    {
                        UpdateWithText();
#if UNITY_EDITOR
                        //force to update text in scene
                        UnityEditor.EditorUtility.SetDirty(this);
#endif
                        break;
                    }
                case TargetType.Image: UpdateWithImage(); break;
                case TargetType.Prefab: UpdateWithPrefab(); break;
                case TargetType.Custom: UpdateWithCustom(); break;
                default: Debug.LogError("LocalizationComponent error: unsupport type=" + type, this); break;
            }
        }

        virtual public string GetCustomTypeName()
        {
            return string.Empty;
        }

        virtual protected void UpdateWithText()
        {
            var textTargetTmp = this.GetComponent<UnityEngine.UI.Text>();
            if (null == textTargetTmp)
            {
                Log.Error("LocalizationComponent InitWithText error: Require UnityEngine.UI.Text Component ! target name=" + this.name, this);
                return;
            }

            textTargetTmp.text = shaco.GameHelper.localization.GetTextFormat(languageKey, formatParams);

#if UNITY_EDITOR
            //force to update text in scene
            UnityEditor.EditorUtility.SetDirty(textTargetTmp);
#endif
        }

        /// <summary>
        /// 获取资源路径
        /// <param name="localizationValue">本地化语言读取的值</param>
        /// <param name="path">资源路径</param>
        /// </summary>
        private void GetPathWithCombine(string localizationValue, out string path)
        {
            path = localizationValue;
            // var splitPaths = localizationValue.Split('|');
            // if (splitPaths.Length != 2)
            // {
            //     Log.Error("LocalizationComponent GetPathWithCombine error: Split format error, only one '|' symbol, key=" + localizationValue);
            //     path = string.Empty;
            //     multiVersionControlRelativePath = string.Empty;
            //     return;
            // }

            // path = splitPaths.Length > 0 ? splitPaths[0] : string.Empty;
            // multiVersionControlRelativePath = splitPaths.Length > 1 ? splitPaths[1] : string.Empty;
        }

        virtual protected bool CanChangeTargetTypeText()
        {
            if (null == this.GetComponent<UnityEngine.UI.Text>())
            {
                Log.Error(string.Format("LocalizationComponent type '{0}' require component '{1}'", type, typeof(UnityEngine.UI.Text).FullName));
                return false;
            }
            else
                return true;
        }

        virtual protected bool CanChangeTargetTypeImage()
        {
            if (null == this.GetComponent<UnityEngine.UI.Image>())
            {
                Log.Error(string.Format("LocalizationComponent type '{0}' require component '{1}'", type, typeof(UnityEngine.UI.Image).FullName));
                return false;
            }
            else
                return true;
        }

        virtual protected bool CanChangeTargetTypePrefab()
        {
            return true;
        }

        virtual protected bool CanChangeTargetTypeCustom()
        {
            return true;
        }

        virtual protected void UpdateWithImage()
        {
            var imageTargetTmp = this.GetComponent<UnityEngine.UI.Image>();
            if (null == imageTargetTmp)
            {
                Log.Error("LocalizationComponent InitWithImagePath error: Require UnityEngine.UI.Image Component ! target name=" + this.name, this);
                return;
            }

            //当游戏没有运行适合可能找不到语言键值，所以要在这里直接退出
            if (!Application.isPlaying && !shaco.GameHelper.localization.ContainsKey(languageKey))
                return;

            string path;
            GetPathWithCombine(languageKey, out path);
            path = shaco.GameHelper.localization.GetTextFormat(path, formatParams);

            if (string.IsNullOrEmpty(path))
            {
                Log.Error("LocalizationComponent InitWithImage erorr: not found path by, key=" + languageKey);
                return;
            }

            if (isAsyncLoad)
            {
                var request = GameHelper.res.LoadAsync<Sprite>(path);
                request.OnCompleted(loadObj =>
                {
                    imageTargetTmp.sprite = (loadObj as Base.IResourceHandle).assetObject as Sprite;
                });
            }
            else
            {
                imageTargetTmp.sprite = GameHelper.res.Load<Sprite>(path).assetObject as Sprite;
            }
        }

        virtual protected void UpdateWithPrefab()
        {
            //当游戏没有运行适合可能找不到语言键值，所以要在这里直接退出
            if (!Application.isPlaying && !shaco.GameHelper.localization.ContainsKey(languageKey))
                return;

            string path;
            GetPathWithCombine(languageKey, out path);
            path = shaco.GameHelper.localization.GetTextFormat(path, formatParams);

            if (string.IsNullOrEmpty(path))
            {
                Log.Error("LocalizationComponent InitWithPrefab erorr: not found path by, key=" + languageKey);
                return;
            }

            if (null != _currentLocalizationPrefab)
            {
                MonoBehaviour.Destroy(_currentLocalizationPrefab);
                _currentLocalizationPrefab = null;
            }

            if (isAsyncLoad)
            {
                var request = GameHelper.res.LoadAsync<GameObject>(path);
                request.OnCompleted(loadObj =>
                {
                    if (null == loadObj)
                        return;

                    var newPrefab = MonoBehaviour.Instantiate((loadObj as Base.IResourceHandle).assetObject as GameObject);
                    _currentLocalizationPrefab = newPrefab;
                    newPrefab.transform.SetParent(this.transform, false);
                });
            }
            else
            {
                var loadObj = GameHelper.res.Load<GameObject>(path);
                if (null == loadObj)
                    return;

                var newPrefab = MonoBehaviour.Instantiate(loadObj.assetObject as GameObject);
                _currentLocalizationPrefab = newPrefab;
                newPrefab.transform.SetParent(this.transform, false);
            }
        }

        virtual protected void UpdateWithCustom()
        {

        }
    }
}

